////////////////////////////////////////////////////////////////////////////////////
//
//	
//							MiTAC Corporation		
//				NO. 187, TIDING BLVD., SEC. 2, TAIPEI, TAIWAN
//	
// 			(c) Copyright 2006, MiTAC Corporation, Taipei, Taiwan  
//						All rights reserved.
//-------------------------------------------------------------------------------------
//
//
//	File:	Sleep.c
//	Description:	OMAP850 timer
//
//	Programer: Visual.Wei
//	Date: 	2006-7-13
//
////////////////////////////////////////////
#include <windows.h>
#include <bsp.h>
#include "kernel_asm.h"
#include "ipl_core.h"

#define INTR_INFO 1
/////////////////////////////////////////////
//#define EARPHONE_TEST
//#define TFLASH_TEST
//#define CHARGE_TEST
//#define AC_TEST
//#define GSM_EXT_NIRQ
//#define TIMER_TEST
#define HALL_TEST
#define KEYPAD_TEST
//////////////////////////////////////////////

#ifdef HALL_TEST
#define HALL_IRQ (IRQ_GPIO_64+79-64)
#endif
#ifdef EARPHONE_TEST
#define EAR_IRQ (IRQ_GPIO_64+81-64)
#endif
#ifdef TFLASH_TEST
#define TFL_IRQ (IRQ_GPIO_96+123-96)
#endif
#ifdef AC_TEST
#define AC_IRQ (IRQ_GPIO_64+71-64)
#endif
#ifdef CHARGE_TEST
#define CHARGE_IRQ (IRQ_GPIO_128+133-128)
#endif
#ifdef GSM_EXT_NIRQ
#define GSM_EXT_IRQ (IRQ_GPIO_160+168-160)
#endif


#ifdef EARPHONE_TEST
static void earphone_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>earphone insert \r\n")));
	LCDTermPrintf(L">>>earphone insert \r\n");
	IPLIntrDoneIrq(EAR_IRQ);
}
#endif
#ifdef TFLASH_TEST
static void tflash_isr()
{
	UINT32 data;
	RETAILMSG (INTR_INFO, (TEXT(">>>tflash insert \r\n")));
	LCDTermPrintf(L">>>tflash insert \r\n");
	data=INREG32(&g_pGPIO4Regs->DATAIN);
	if(data&(1 << (123%32)))
	{
		CLRREG32(&g_pGPIO4Regs->INTEDGE, (1 << (123%32)));
		LCDTermPrintf(L">>>tflash ok \r\n");
	}
	else
	{
		SETREG32(&g_pGPIO4Regs->INTEDGE, (1 << (123%32)));
		LCDTermPrintf(L">>>tflash fail\r\n");
	}
	IPLIntrDoneIrq(TFL_IRQ);
}
#endif
#ifdef HALL_TEST
static void hall_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>hall \r\n")));
	LCDTermPrintf(L">>>hall \r\n");
	IPLIntrDoneIrq(HALL_IRQ);
}
#endif
#ifdef AC_TEST
static void ac_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>ac \r\n")));
	LCDTermPrintf(L">>>ac \r\n");
	IPLIntrDoneIrq(AC_IRQ);
}
#endif
#ifdef CHARGE_TEST
static void charge_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>charge\r\n")));
	LCDTermPrintf(L">>>charge  \r\n");
	IPLIntrDoneIrq(CHARGE_IRQ);
}
#endif
#ifdef GSM_EXT_NIRQ
static void gsm_charge_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>charge\r\n")));
	LCDTermPrintf(L">>>charge  \r\n");
	IPLIntrDoneIrq(GSM_EXT_IRQ);
}
#endif
#ifdef TIMER_TEST
static void timer_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>timer\r\n")));
	LCDTermPrintf(L">>>timer \r\n");
	IPLIntrDoneIrq(IRQ_TIMER32K);
}
#endif
#ifdef KEYPAD_TEST
static void keypad_isr()
{
	RETAILMSG (INTR_INFO, (TEXT(">>>key\r\n")));
	LCDTermPrintf(L">>>key \r\n");
	IPLIntrDoneIrq(IRQ_ARMIO_KEYPAD);
}
#endif
static void intr_start()
{
	OMAP730_GPIO_REGS *g_pGPIO3Regs;
	OMAP730_GPIO_REGS *g_pGPIO4Regs;
	OMAP730_GPIO_REGS *g_pGPIO5Regs;
#ifdef GSM_EXT_NIRQ
	OMAP730_CONFIG_REGS * pConfigRegs;
#endif
#ifdef KEYPAD_TEST
	OMAP730_ARMIO_REGS *pARMIORegs = OALPAtoUA(OMAP730_ARMIO_REGS_PA);
#endif
	g_pGPIO3Regs = OALPAtoUA(OMAP730_GPIO3_REGS_PA);
	g_pGPIO4Regs = OALPAtoUA(OMAP730_GPIO4_REGS_PA);
	g_pGPIO5Regs = OALPAtoUA(OMAP730_GPIO5_REGS_PA);
	
#ifdef EARPHONE_TEST
	//earphone insert,GPIO_81 as iutput pin, interrupt
	IPLIntrRequestIrq(EAR_IRQ,earphone_isr);
	SETREG32(&g_pGPIO3Regs->DATADIR, (1 << (81%32)));
	IPLIntrEnableIrq(EAR_IRQ);
#endif
#ifdef TFLASH_TEST
	//earphone insert,GPIO_123 as iutput pin, interrupt
	IPLIntrRequestIrq(TFL_IRQ,tflash_isr);
	SETREG32(&g_pGPIO4Regs->DATADIR, (1 << (123%32)));
	IPLIntrEnableIrq(TFL_IRQ);
#endif
#ifdef CHARGE_TEST
	//charge status change,GPIO_133 as iutput pin, interrupt
	IPLIntrRequestIrq(CHARGE_IRQ,charge_isr);
	SETREG32(&g_pGPIO5Regs->DATADIR, (1 << (133%32)));
	IPLIntrEnableIrq(CHARGE_IRQ);
#endif
#ifdef HALL_TEST
	//HALL open & close,GPIO_79 as iutput pin, interrupt
	IPLIntrRequestIrq(HALL_IRQ,hall_isr);
	SETREG32(&g_pGPIO3Regs->DATADIR, (1 << (79%32)));
	CLRREG32(&g_pGPIO3Regs->INTEDGE, (1 << (79%32)));
	IPLIntrEnableIrq(HALL_IRQ);
#endif
#ifdef AC_TEST
	//ac insert,GPIO_71 as iutput pin, interrupt
	IPLIntrRequestIrq(AC_IRQ,ac_isr);
	SETREG32(&g_pGPIO3Regs->DATADIR, (1 << (71%32)));
	CLRREG32(&g_pGPIO3Regs->INTEDGE, (1 << (71%32)));
	IPLIntrEnableIrq(AC_IRQ);
#endif
#ifdef GSM_EXT_NIRQ
#define BIT0    0x00000001
#define BIT1    0x00000002
#define BIT2    0x00000004
#define BIT3    0x00000008
	pConfigRegs = (OMAP730_CONFIG_REGS *) OALPAtoUA( OMAP730_CONFIG_REGS_PA );
	data = INREG32(&pConfigRegs->IO_CONFIG10);
	data &= ~(BIT3 | BIT2 | BIT1|BIT0);          // Mask out CPIN_5 content
	data |= (BIT3 | BIT2);                 // Config to CPIN_5
	OUTREG32(&pConfigRegs->IO_CONFIG10, data);
	
	//CPIN_5==GPIO_168+5
	IPLIntrRequestIrq(GSM_EXT_IRQ,gsm_charge_isr);
	SETREG32(&g_pGPIO6Regs->DATADIR, (1 << (168%32)));
	CLRREG32(&g_pGPIO6Regs->INTEDGE, (1 << (168%32)));
	IPLIntrEnableIrq(GSM_EXT_IRQ);
#endif
	//software IRQ
	//IPLIntrDoneIrq(53);
	//IPLIntrEnableIrq(53);
	//SETREG32(&g_pIntcL2ARegs->SIR, (1<<21));
#ifdef TIMER_TEST
	//32k_timer
	IPLIntrRequestIrq(IRQ_TIMER32K,timer_isr);
	IPLTimerStart();
	IPLIntrEnableIrq(IRQ_TIMER32K);
#endif

#ifdef KEYPAD_TEST
	IPLIntrRequestIrq(IRQ_ARMIO_KEYPAD,keypad_isr);
	// unMask keyboard interrupt
    	CLRREG16(&pARMIORegs->KBD_INT_MASK, OMAP730_ARMIO_KBD_MASKIT);
	IPLIntrEnableIrq(IRQ_ARMIO_KEYPAD);
#endif
}

void IPL_Core_Sleep()
{
	OMAP730_CLKM_REGS * pCLKM;
	//OMAP730_EMIF_REGS *pEMIFRegs;

	pCLKM = OALPAtoUA(OMAP730_CLKM_REGS_PA);
	//pEMIFRegs = OALPAtoUA(OMAP730_EMIF_REGS_PA);

	/////////////////////////////////////
	//
	//	Before Sleep
	//
	/////////////////////////////////////
	
	intr_start();
	
	//wake up by unmasked interrupts
	SETREG16(&pCLKM->IDLECT1, 1 << 10);

	//active ARMPER_CK
	CLRREG16(&pCLKM->IDLECT1, 1 << 2);
	SETREG16(&pCLKM->IDLECT2, 1 << 2);

	//active ARMXOR_CK
	CLRREG16(&pCLKM->IDLECT1, 1 << 1);
	SETREG16(&pCLKM->IDLECT2, 1 << 1);
	
	_arm9_deep_sleep();//sleep point

	/////////////////////////////////////
	//
	//	After Wake Up
	//
	/////////////////////////////////////
}
